package com.gpsnav.file;

import java.util.Enumeration;
/*import javax.microedition.io.Connector;
import javax.microedition.io.file.FileConnection;
import javax.microedition.io.file.FileSystemRegistry;
import net.rim.device.api.system.Characters;
import net.rim.device.api.system.DeviceInfo;
import net.rim.device.api.system.KeypadListener;
import net.rim.device.api.ui.MenuItem;
import net.rim.device.api.ui.UiApplication;
import net.rim.device.api.ui.component.Dialog;
import net.rim.device.api.ui.component.Menu;
import net.rim.device.api.ui.component.GaugeField;
import net.rim.device.api.ui.container.MainScreen;*/
import net.rim.device.api.io.*;
import net.rim.device.api.ui.*;
import net.rim.device.api.ui.container.*;
import net.rim.device.api.ui.component.*;
import net.rim.device.api.ui.text.*;
import net.rim.device.api.system.*;

import java.io.*;
import java.util.*;
import javax.microedition.io.*;
import javax.microedition.io.file.*;
import javax.microedition.location.*;


import com.gpsnav.bo.Waypoint;
import com.gpsnav.dao.WaypointsDAO;

import com.gpsnav.screen.*;
import com.gpsnav.util.*;
import com.gpsnav.ui.*;
import com.gpsnav.bo.Options;

public class FileExplorerScreen extends MainScreen{
    
    private FileExplorerListFieldImpl _list;
    private String _parentRoot;
    
    String data;
    
    String latTag_LOC = "<coord lat=\"";
    String lonTag_LOC = "lon=\"";
    String nameTag_LOC = "<name id=\"";
    String typeTag_LOC = "<type>";
    String linkTag_LOC = "<link";
    
    String urlTag_GPX = "<url>";
    String typeTag_GPX = "<type>";
    String desc1Tag_GPX = "<groundspeak:short_description html=\"False\">";
    String desc2Tag_GPX = "<groundspeak:long_description html=\"False\">";
    String hintTag_GPX = "<groundspeak:encoded_hints>";
    String lonTag_GPX = "lon=";
    String nameTag_GPX = "<desc>";
    String discTag_GPX = "<groundspeak:long_description";
    String latTag_GPX = "<wpt lat=\""; 
    
    GaugeField  gauge = null; //new GaugeField("status",0,10,1,GaugeField.PERCENT);
    CustomVerticalFieldManager screen = new CustomVerticalFieldManager();
    MainScreen thisScreen = null;
    private LabelField slf = new LabelField(" ");

    public FileExplorerScreen() {
        thisScreen = this;
        setTitle("Please Select File:");

        _list = new FileExplorerListFieldImpl();
//        add(gauge);
        screen.add(_list);
        add(screen);
        
        readRoots(null);
   }
    
    public void close() {
        ListWaypointsScreen listScreen = new ListWaypointsScreen();
        UiApplication.getUiApplication().popScreen();
        
        WaypointsDAO dao = new WaypointsDAO();
        Waypoint[] wpList = dao.loadWaypoints();
        listScreen.setWaypoints(wpList);
        UiApplication.getUiApplication().pushScreen(listScreen);
        
    }
    
    public boolean keyChar(char c, int status, int time) {
        switch (c) {
            case Characters.ENTER:
                return selectAction();
                
            case Characters.ESCAPE:
                if ( goBack() ) return true;
                
            default:
                return super.keyChar(c, status, time);
        }
    }

    
    public void makeMenu(Menu menu, int instance) {
        if (instance == Menu.INSTANCE_DEFAULT) {
            menu.add(_selectItem);
            if ( _parentRoot != null ) menu.add( _backItem );
        }

        super.makeMenu(menu, instance);
    }
    
    public boolean navigationClick(int status, int time) {
        if ((status & KeypadListener.STATUS_TRACKWHEEL) != KeypadListener.STATUS_TRACKWHEEL) {
            return selectAction();
        }
        return super.navigationClick(status, time);
    }

    
    private void readRoots(String root){
        _parentRoot = root;
        
        // Clear whats in the list.
        _list.removeAll();

        FileConnection fc = null;
        Enumeration rootEnum = null;

        if (root != null) {
            // Open the file system and get the list of directories/files.
            try {
                fc = (FileConnection)Connector.open("file:///" + root);
                rootEnum = fc.list();
            } 
            catch (Exception ioex) {} 
            finally {
                
                if (fc != null) {   
                    // Everything is read, make sure to close the connection.
                    try {
                        fc.close();
                        fc = null;
                    } 
                    catch (Exception ioex) {}
                }
            }
        }
       
        if (rootEnum == null) rootEnum = FileSystemRegistry.listRoots();

        // Read through the list of directories/files.
        while (rootEnum.hasMoreElements()) {
            String file = (String)rootEnum.nextElement();
            if (root != null) file = root + file;             
            readSubroots(file);
        }
    }
    
    private void readSubroots(String file) {
        FileConnection fc = null;
        
        try {
            fc = (FileConnection)Connector.open("file:///" + file);
            // Create a file holder from the FileConnection so that the connection is not left open.
            if (fc.isDirectory() 
                        || fc.getName().toUpperCase().endsWith(".GPX")
                        || fc.getName().toUpperCase().endsWith(".LOC")
                        || fc.getName().toUpperCase().endsWith(".GPX.REM")
                        || fc.getName().toUpperCase().endsWith(".LOC.REM")
                       || fc.getName().toUpperCase().endsWith(".ASPX")   // this is temp for pre-4.5 os
                        ) {
                FileExplorerFileHolder fileholder = new FileExplorerFileHolder(file);
                fileholder.setDirectory(fc.isDirectory());
                _list.add(fileholder);
            }

        } 
        catch (Exception ioex) {} 
        finally {
            if (fc != null) {
                // Everything is read, make sure to close the connection.
                try {
                    fc.close();
                    fc = null;
                } 
                catch (Exception ioex) {}
            }
        }
    }
    
    private boolean selectAction() {
        final FileExplorerFileHolder fileholder = (FileExplorerFileHolder)_list.get(_list, _list.getSelectedIndex());
        final ReadFile readFile = new ReadFile();
        int counter=0;
        
        if (fileholder != null) {
            if (fileholder.isDirectory()) readRoots(fileholder.getPath()); 
            else{

                screen.deleteAll();
                final LabelField stage = new LabelField("Please wait while the file is imported...");
                screen.add(stage);
                screen.add(new LabelField("  "));
                screen.add(slf);
                Thread t = new Thread(new Runnable()  {
                  public void run() {
                
                    String dir = fileholder.getDir();
                    String type = dir.substring(dir.length()-3,dir.length());
                    
                    WaypointsDAO dao = new WaypointsDAO();
                    Waypoint[] wpts = null;
                    if(type.equalsIgnoreCase("gpx")){
                        data = readFile.getInput(dir);
                        wpts = GPXParser.parseGPX(data);
                    } else if(type.equalsIgnoreCase("loc")){
                        data = readFile.getInput(dir);
                        wpts = LOCParser.parseLOC(data);
                    } else if(type.equalsIgnoreCase("spx")){    //temp
                        data = readFile.getInput(dir);          //for 
                        wpts = LOCParser.parseLOC(data);        //pre-4.5 os
                    } 
                    
                    ProgressBar progress = new ProgressBar(wpts.length, "Storing Waypoints...");
        
                    synchronized(UiApplication.getEventLock()) {
                        progress.open();
                    }

                    String msg = "";
                    if (wpts != null && wpts.length > 0) {
                        
                        int insertedWaypoints = 0;
                        int updatedWaypoints = 0;
                        
                        for (int i = 0;i<wpts.length;i++) {
                            Waypoint oldWp = dao.getWaypoint(wpts[i].getKeyName());
                            if (oldWp == null) {
                                dao.storeWaypoint(wpts[i],false);
                                insertedWaypoints++;
                            } else {
                                dao.deleteWaypoint(oldWp,false);
                                dao.storeWaypoint(wpts[i],false);
                                updatedWaypoints++;
                            }
                            dao.commitWaypoints();
                            synchronized(UiApplication.getEventLock()) {
                                progress.update(i);
                            }
                        }

                        synchronized(UiApplication.getEventLock()) {
                            progress.close();
                        }

                        
                        //msg = wpts.length+" Point(s) have been added to the database!";
                        msg = insertedWaypoints + " Point(s) added.  " + updatedWaypoints + " Points updated.";
                        
                    } else {
                        msg = "no waypoints found";
                    }

                    synchronized(UiApplication.getEventLock()) {
                        stage.setText("Import Complete.  " + msg);
                        slf.setText("Please use the \"Close\" menu item to return to the List Waypoints screen");
                    }

                  }
                });
                t.start();





                //bar.close();
            }
        }
        return true;
    }
    
    
   //void updateList() { synchronized (_uiApp.getAppEventLock()) { readRoots(_parentRoot); }; }
    
    private boolean goBack() {
        if ( _parentRoot != null ) {
            String backParentRoot = _parentRoot.substring(0, _parentRoot.lastIndexOf('/'));
            backParentRoot = backParentRoot.substring(0, backParentRoot.lastIndexOf('/') + 1);
            
            if (backParentRoot.length() > 0) readRoots(backParentRoot);            
            else readRoots(null);
                        
            return true;
        }
        return false;
    }
    
    private void cancel(){
        //UiApplication.getUiApplication().popScreen();
    }
    
    private MenuItem _selectItem = new MenuItem("Select" , 500, 500) { public void run() { selectAction(); } };
    private MenuItem _backItem = new MenuItem("Go Back" , 500, 500 ) { public void run() { goBack(); } };
    private MenuItem _cancelItem = new MenuItem("Cancel", 500, 500) { public void run() { cancel(); } };


    //gpx file support
    
    private String getTag_GPX(String startTag, int offset, String endTag){
        String val = "";
        try{
            int start = data.indexOf(startTag)+startTag.length()+offset;
            data = data.substring(start, data.length());
            int end = data.indexOf(endTag);
            val = data.substring(0, end);
            data = data.substring(end+1);
        }catch(Exception e){}
        return val;
    }
    
    private double getLat_GPX(){
        String lat = "";
        try{
            int start = data.indexOf(latTag_GPX) + latTag_GPX.length();
            data = data.substring(start,data.length());
            int end = data.indexOf("\"");
            lat = data.substring(0,end);
            data = data.substring(end+1);
        }catch(Exception e){}
        return Double.parseDouble(lat);
    }
    private double getLon_GPX(){
        String lon = "";
        try{
            int start = data.indexOf(lonTag_GPX)+lonTag_GPX.length()+1;
            data = data.substring(start, data.length());
            int end = data.indexOf("\"");
            lon = data.substring(0,end);
            data = data.substring(end+1);
        }catch(Exception e) {}
        return Double.parseDouble(lon);
    }
    private String getName_GPX(){
        String name = "";
        try{
            int start = data.indexOf(nameTag_GPX)+nameTag_GPX.length();
            data = data.substring(start, data.length());
            int end = data.indexOf("</desc>");
            name = data.substring(0, end);
            data = data.substring(end+1);
        }catch(Exception e){}
        return name;
    }
    private String getHint_GPX(){
        String name = "";
        try{
            int start = data.indexOf(hintTag_GPX)+hintTag_GPX.length();
            data = data.substring(start, data.length());
            int end = data.indexOf("</groundspeak:encoded_hints>");
            name = data.substring(0, end);
            data = data.substring(end+1);
        }catch(Exception e ) {}
        return name;
    }
    private String getDiscription_GPX(){
        String disc = "";
        try{
            int start = data.indexOf(discTag_GPX)+discTag_GPX.length()+13;
            data = data.substring(start, data.length());
            int end = data.indexOf("</groundspeak");
            disc = data.substring(0, end);
            data = data.substring(end+1);
        }catch(Exception e) {}
        return disc;
    }
    
    //loc file support
    private double getLat_LOC(){
        String lat;
        int start = data.indexOf(latTag_LOC) + latTag_LOC.length();
        data = data.substring(start,data.length());
        int end = data.indexOf("\"");
        lat = data.substring(0,end);
        data = data.substring(end+1);
        return Double.parseDouble(lat);
    }
    
    private double getLon_LOC(){
        String lon;
        int start = data.indexOf(lonTag_LOC)+lonTag_LOC.length();
        data = data.substring(start, data.length());
        int end = data.indexOf("\"");
        lon = data.substring(0,end);
        data = data.substring(end+1);
        return Double.parseDouble(lon);
    }
    
    private String getName_LOC(){
        String name;
        int start = data.indexOf(nameTag_LOC)+nameTag_LOC.length();
        data = data.substring(start, data.length());
        int end = data.indexOf("\">");
        name = data.substring(0, end);
        data = data.substring(end+1);
        
        return name;
    }
    
    private String getType_LOC(){
        String type;
        int start = data.indexOf(typeTag_LOC)+typeTag_LOC.length();
        data = data.substring(start, data.length());
        int end = data.indexOf("</type");
        type = data.substring(0, end);
        data = data.substring(end+1);
        return type;
    }
    
    private String getLink_LOC(){
        String link;
        int start = data.indexOf(linkTag_LOC)+linkTag_LOC.length();
        data = data.substring(start, data.length());
        start = data.indexOf(">")+1;
        data = data.substring(start, data.length());
        int end = data.indexOf("</");
        link = data.substring(0, end);
        data = data.substring(end+1);
        return link;
    }

    protected void paintBackground(Graphics g) {
        if (Options.getNightMode()) {
            g.setBackgroundColor(Color.BLACK);
            g.setColor(Color.RED);
        } else {
            g.setBackgroundColor(Color.WHITE);
            g.setColor(Color.BLACK);
        }
        g.clear();
    }

}


